package capricornus.components.window
{
	import capricornus.components.label.Label;
	import capricornus.components.utils.DragController;
	import capricornus.components.utils.window.WindowUtils;
	import capricornus.components.window.event.WindowEvent;
	import capricornus.core.StageManager;
	import capricornus.events.StageEvent;
	
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	
	[Event(name="windowClosed", type="capricornus.components.window.event.WindowEvent")]
	public class Window extends Sprite
	{
		/**
		 * 是否设置默认的窗口类型；如果为true，则自动设置窗口类型；默认是false 
		 */		
		public static const SET_DEFAULT_WINDOW_STYLE:Boolean = false;
		
		protected var _owner:DisplayObjectContainer;
		
		protected var _dragArea:InteractiveObject;
		
		private var _xAlignType:int = WindowAlignType.LEFT;
		private var _yAlignType:int = WindowAlignType.TOP;
		private var _xScale:Number;
		private var _yScale:Number;
		
		/**
		 * 窗口宽高，在默认窗口类型时有用，自定义窗口时可以不理 
		 */		
		protected var _windowWidth:int = 100;
		protected var _windowHeight:int = 60;
		/**
		 * 默认窗口类型时有效 
		 */		
		protected var _txtTitle:Label;
		
		protected var _validRect:Rectangle = null;
		
		private var _dragController:DragController = null;
		
		private var _btnClose:InteractiveObject;
		private var _panel:Sprite;
		
		public function Window( owner:DisplayObjectContainer )
		{
			this._owner = owner;
			super();
			init();
		}
		
		private function init():void
		{
			this.cacheAsBitmap = true;
			this.addEventListener( Event.ADDED_TO_STAGE, onAddToStage, false, 0, true );
			this.addEventListener( Event.REMOVED_FROM_STAGE, onRemoveFromStage, false, 0, true );
			
			if( SET_DEFAULT_WINDOW_STYLE )
			{
				setDefaultStyle();
			}
		}
		
		public function destroy():void
		{
			_validRect = null;
			_owner = null;
			if( _dragController != null )
			{
				_dragController.destroy();
				_dragController.removeEventListener( DragController.DRAG_STOP, onDragStop );
				_dragController = null;
			}
			close();
			if( _btnClose != null )
			{
				_btnClose.removeEventListener( MouseEvent.CLICK, onClickClose );
				_btnClose = null;
			}
			if( _panel != null )
			{
				_panel.removeEventListener( MouseEvent.MOUSE_DOWN, onMouseDown );
			}
		}
		
		/**
		 * 设置默认窗口类型 
		 * 
		 */		
		protected function setDefaultStyle():void
		{
			panel = WindowUtils.createWindow( windowWidth, windowHeight );
			
			_txtTitle = panel.getChildByName("txtTitle") as Label;
		}
		
		protected function get windowWidth():int
		{
			return _windowWidth;
		}
		
		protected function get windowHeight():int
		{
			return _windowHeight;
		}
		
		/**
		 * 设置panel内容 
		 * @param value
		 * 
		 */		
		protected function set panel( value:Sprite ):void
		{
			if( _panel != null && value != null )
			{
				throw new Error( "不能重复设置panel" );
			}
			_panel = value;
			if( _panel==null ) return;
			addChild( _panel );
			_panel.cacheAsBitmap = true;
			
			_btnClose = _panel.getChildByName("btnclose") as InteractiveObject;
			if( _btnClose != null )
			{
				_btnClose.addEventListener( MouseEvent.CLICK, onClickClose, false, 0, true );
			}
			dragArea = _panel.getChildByName("btndrag") as InteractiveObject;
			
			_panel.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDown, false, 0, true );
		}
		
		protected function get panel():Sprite
		{
			return _panel;
		}
		
		protected function set dragArea( value:InteractiveObject ):void
		{
			if( _dragController != null )
			{
				_dragController.destroy();
				_dragController.removeEventListener( DragController.DRAG_STOP, onDragStop );
				_dragController = null;
			}
			_dragArea = value;
			if( value != null )
			{
				_validRect = this.getBounds( this );
				_dragController = new DragController( this, value );
				_dragController.addEventListener( DragController.DRAG_STOP, onDragStop, false, 0, true );
			}
		}
		
		protected function set validRect( value:Rectangle ):void
		{
			_validRect = value;
		}
		
		protected function get validRect():Rectangle
		{
			if( _validRect==null )
			{
				_validRect = this.getBounds( this );
			}
			return _validRect;
		}
		
		protected function canClose():Boolean
		{
			return true;
		}
		
		public function setLocation( x:int, y:int ):void
		{
			if( x < 0 ) x = 0;
			if( y < 0 ) y = 0;
			if( x > StageManager.stageWidth - _validRect.width/2 ) x = StageManager.stageWidth - _validRect.width/2;
			if( y > StageManager.stageHeight - _validRect.height/2 ) y = StageManager.stageHeight - _validRect.height/2;
			
			this.x = x;
			this.y = y;
			if( !_isResize )
			{
				resetXYScale();
			}
		}
		
		public function setAlignType( xAlignType:int, yAlignType:int ):void
		{
			_xAlignType = xAlignType;
			_yAlignType = yAlignType;
			resetXYScale();
		}
		
		public function setCenterLocation():void
		{
			var rect:Rectangle = validRect;
			setLocation( (StageManager.stageWidth - rect.x - rect.width)/2, (StageManager.stageHeight - rect.y - rect.height)/2 );
		}
		
		public function show():void
		{
			if( null==parent )
			{
				_owner.addChild( this );
			}
		}
		
		public function showCenter():void
		{
			show();
			setCenterLocation();
		}
		
		public function close():void
		{
			if( parent != null )
			{
				if( canClose() )
				{
					parent.removeChild( this );
					dispatchEvent( new WindowEvent( WindowEvent.WINDOW_CLOSED ) );
				}
			}
		}
		
		private function onDragStop( e:Event ):void
		{
			setLocation( x, y );
			resetXYScale();
		}
		
		private function resetXYScale():void
		{
			if( _xAlignType==WindowAlignType.SCALE )
			{
				_xScale = (this.x + validRect.x + validRect.width/2) / StageManager.stageWidth;
			}
			else if( _xAlignType==WindowAlignType.RIGHT )
			{
				_xScale = StageManager.stageWidth - this.x;
			}
			if( _yAlignType==WindowAlignType.SCALE )
			{
				_yScale = (this.y + validRect.y + validRect.height/2) / StageManager.stageHeight;
			}
			else if( _yAlignType==WindowAlignType.DOWN )
			{
				_yScale = StageManager.stageHeight - this.y;
			}
		}
		
		private function onAddToStage( e:Event ):void
		{
			StageManager.instance.addEventListener( StageEvent.RESIZE, onResize, false, 0, true );
		}
		
		private function onRemoveFromStage( e:Event ):void
		{
			StageManager.instance.removeEventListener( StageEvent.RESIZE, onResize );
		}
		
		private var _isResize:Boolean = false;
		private function onResize( e:StageEvent ):void
		{
			var x:int = this.x;
			if( _xAlignType==WindowAlignType.LEFT )
			{
				//x不动
			}
			else if( _xAlignType==WindowAlignType.RIGHT )
			{
				x = StageManager.stageWidth - _xScale;	
			}
			else if( _xAlignType==WindowAlignType.SCALE )
			{
				x = StageManager.stageWidth * _xScale - validRect.width/2 - validRect.x;
			}
			var y:int = this.y;
			if( _yAlignType==WindowAlignType.TOP )
			{
				//y不动
			}
			else if( _yAlignType==WindowAlignType.DOWN )
			{
				y = StageManager.stageHeight - _yScale;
			}
			else if( _yAlignType==WindowAlignType.SCALE )
			{
				y = StageManager.stageHeight * _yScale - validRect.height/2 - validRect.y;
			}
			_isResize = true;
			setLocation( x, y );
			_isResize = false;
		}
		
		private function onClickClose( e:MouseEvent ):void
		{
			close();
		}
		
		private function onMouseDown( e:MouseEvent ):void
		{
			this.parent.setChildIndex( this, this.parent.numChildren - 1 );
		}
	}
}










